package com.tina.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.internal.util.AlipaySignature;
import com.tina.config.AlipayConfigInfo;

import com.tina.entity.AlipayRefun;
import com.tina.entity.CheckPay;
import com.tina.entity.Orders;
import com.tina.entity.OrdersMsgVo;
import com.tina.service.IOrdersService;
import com.tina.util.AliPayUtil;
import com.tina.util.MqUtil;
import com.tina.websocket.WebSocketServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RestController;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;

import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author tina
 * @Time 2020/10/26 上午9:01
 * @Version 1.0
 * @Content
 **/
@RestController
@RequestMapping("/")
public class AlipayControlller {

    @Autowired
    private IOrdersService ordersService;

    private Logger logger = LoggerFactory.getLogger(AlipayControlller.class);
    @Value("${mq.pay.topic}")
    private String payTopic;

    @Value("${mq.pay.tag.success}")
    private String payTag;

    @Resource
    private AliPayUtil aliPayUtil;

    @Autowired
    private MqUtil mqUtil;

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 快捷支付调用支付宝支付接口
     *
     * @param model，id，payables，
     * @return Object
     */
    @RequestMapping("alipaySum")
    public void alipayIumpSum(Model model, String WIDout_trade_no, String WIDsubject, String WIDtotal_amount, String WIDbody,
                              HttpServletResponse response)
            throws Exception {
        String payables = WIDout_trade_no;
        // 订单名称，必填(必须是数字)
        String subject = WIDsubject;
        // 付款金额，必填
        String total_fee = WIDtotal_amount;
        // 商品描述，可空
        String body = WIDbody;
        // 获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfigInfo.gatewayUrl, AlipayConfigInfo.app_id,
                AlipayConfigInfo.merchant_private_key, "json", AlipayConfigInfo.charset,
                AlipayConfigInfo.alipay_public_key, AlipayConfigInfo.sign_type);
        // 设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfigInfo.return_url);
        alipayRequest.setNotifyUrl(AlipayConfigInfo.notify_url);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        // 商户订单号，商户网站订单系统中唯一订单号，必填
        String out_trade_no = sdf.format(new Date());
        // 付款金额，必填
        String total_amount = payables.replace(",", "");
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount
                + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + body + "\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
        // 请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        System.out.println(result);


        response.setContentType("text/html; charset=gbk");
        PrintWriter out = response.getWriter();
        out.print(result);
        System.out.println("out->{}" + out);
    }

    /**
     * 支付成功的回调接口
     *
     * @return
     */
    @RequestMapping("notifyPayResult")
    public void notifyPayResult(HttpServletRequest request) throws Exception {
        logger.info("<-----进入支付宝回调----->");
        CheckPay checkPay = checkePay(request);
        Orders orders = ordersService.selectOrdersById(checkPay.getOutTradeNo());
        if (checkPay.getSignVerified()) {
            //验签通过:根据订单号查找订单,防止多次回调的问题.只处理支付成功的订单: 修改交易表状态,支付成功
            ordersService.checkOrder(checkPay.getOutTradeNo());
            try {
                mqUtil.sendMsg(payTopic, payTag, orders.getOrderId().toString(), JSON.toJSONString(orders));
                webSocketServer.sendMessage(new OrdersMsgVo(null, null, "支付成功！", true));
            } catch (Exception e) {
                Boolean set = set(orders, checkPay.getOutTradeNo(), checkPay.getTradeNo());
                logger.info("异常退款->{}", set);
                e.printStackTrace();
                webSocketServer.sendMessage(new OrdersMsgVo(null, null, "支付失败，金额即将退回于你！", false));
            }
        } else {
            //验签不通过
            Boolean set = set(orders, checkPay.getOutTradeNo(), checkPay.getTradeNo());
            webSocketServer.sendMessage(new OrdersMsgVo(null, null, "验签失败，金额即将退回于你！", false));
            logger.info("-->验签失败退款");
        }
    }


    /**
     * 退款
     *
     * @param orders
     * @param getOutTradeNo
     * @param getTradeNo
     * @return
     * @throws Exception
     */
    private Boolean set(Orders orders, String getOutTradeNo, String getTradeNo) throws Exception {
        AlipayRefun alipayRefun = new AlipayRefun();
        alipayRefun.setGoodsName(orders.getTitle());
        alipayRefun.setOutTradeNo(getOutTradeNo);
        alipayRefun.setRefundAmount(orders.getTotalAmount());
        alipayRefun.setTradeNo(getTradeNo);
        alipayRefun.setGoodsName(orders.getTitle());
        alipayRefun.setQuantity(orders.getNumber());
        return aliPayUtil.alipayRefund(alipayRefun);
    }

    /**
     * 校验证支付宝支付后回调
     *
     * @param request
     * @return
     */
    private CheckPay checkePay(HttpServletRequest request) {
        // 1.从支付宝回调的request域中取值放到map中
        Map<String, String[]> requestParams = request.getParameterMap();

        Map<String, String> params = new HashMap();
        for (String name : requestParams.keySet()) {
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }
        //2.封装必须参数
        // 商户订单号 新接口 交易状态去掉了
        String outTradeNo = params.get("out_trade_no");
        // 支付宝交易号
        String tradeNo = params.get("trade_no");
        logger.info("outTradeNo:{},tradeNo:{}", outTradeNo, tradeNo);
        //3.签名验证(对支付宝返回的数据验证，确定是支付宝返回的)
        CheckPay checkPay = new CheckPay(false, outTradeNo, tradeNo);
        try {
            //3.1调用SDK验证签名
            checkPay.setSignVerified(AlipaySignature.rsaCheckV1(params, AlipayConfigInfo.alipay_public_key, AlipayConfigInfo.charset, AlipayConfigInfo.sign_type));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return checkPay;
    }


}
